﻿using System;
using System.Collections;
using System.Collections.Generic;
using ConceptsFramework.AbstractConceptElements;
using ConceptsFramework.Containers.Global;
using ConceptsFramework.DerivedRelationships;

namespace ConceptsFramework.Containers.Generic
{
    public class BindableConceptContainer<T>: IEnumerable<T> where T:AbstractBindableConcept
    {
        public Dictionary<string, T> Container;

        public BindableConceptContainer()
        {
            Container = new Dictionary<string, T>();
        }

        /// <summary>
        /// Defines the ParentConcept for the current collection
        /// </summary>
        public AbstractBindableConcept ParentConcept
        {
            get; 
            set;
        }

        public Func<T, string> ConceptKeyRetriever
        {
            get; set;
        }

        private void AddOnGlobalContainer(T concept)
        {
            if (ParentConcept != null)
            {
                // Any calls of Add in BindableConceptContainer<T> 
                // needs to register the current object in the GlobalConceptContainer
                if (ParentConcept.IsRelationshipAutorized<HostRelationship>())
                {
                    if (concept.IsRelationshipAutorized<IsContainedRelationship>())
                    {
                        HostRelationship anHostRelationship = new HostRelationship();
                        anHostRelationship.LeftConcept = ParentConcept;
                        anHostRelationship.RightConcepts = new List<AbstractBindableConcept>();
                        anHostRelationship.RightConcepts.Add(concept);
                        anHostRelationship.Commit<HostRelationship, IsContainedRelationship>(false);
                    }
                }
            }

            if (!(this is GlobalConceptsSingletonContainer))
                GlobalConceptsSingletonContainer.Instance.Add(concept);
        }

        public void Add(T concept)
        {
            string strConceptKey = "";
            if (ConceptKeyRetriever!=null)
            {
                strConceptKey = ConceptKeyRetriever(concept);
            }
            if ((strConceptKey =="") || (strConceptKey ==null))
            {
                strConceptKey = concept.ID;
            }
            if (!Container.ContainsKey(strConceptKey))
                Container.Add(strConceptKey, concept);
            AddOnGlobalContainer(concept);
        }

       
        public T Retrieve(string strName)
        {
            if (!Container.ContainsKey(strName))
                return null;
            return Container[strName];
        }

        public bool Contains(string strName)
        {
            return Container.ContainsKey(strName);
        }

        public IEnumerator<T> GetEnumerator()
        {
            return (Container.Values.GetEnumerator());
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return (Container.Values.GetEnumerator());
        }
    }
}
